package com.cvte.sunkit.tools

import android.app.ActivityManager
import android.content.Context
import android.util.Log
import java.io.BufferedReader
import java.io.FileInputStream
import java.io.InputStreamReader


object MemoryTool {

    private var mMemTotal = 0L  // 所有可用RAM大小。
    private var mMemAvail = 0L   // LowFree与HighFree的总和，被系统留着未使用的内存。

    private const val BYTES_PER_MEGA = 1024 * 1024

    private const val TAG = "MemoryTool"

    /**
     *
    MemTotal:       所有可用RAM大小。
    MemFree:        LowFree与HighFree的总和，被系统留着未使用的内存。
    Buffers:        用来给文件做缓冲大小。
    Cached:         被高速缓冲存储器（cache memory）用的内存的大小（等于diskcache minus SwapCache）。
    SwapCached:     被高速缓冲存储器（cache memory）用的交换空间的大小。已经被交换出来的内存，仍然被存放在swapfile中，用来在需要的时候很快的被替换而不需要再次打开I/O端口。
    Active:         在活跃使用中的缓冲或高速缓冲存储器页面文件的大小，除非非常必要，否则不会被移作他用。
    Inactive:       在不经常使用中的缓冲或高速缓冲存储器页面文件的大小，可能被用于其他途径。
    SwapTotal:      交换空间的总大小。
    SwapFree:       未被使用交换空间的大小。
    Dirty:          等待被写回到磁盘的内存大小。
    Writeback:      正在被写回到磁盘的内存大小。
    AnonPages：     未映射页的内存大小。
    Mapped:         设备和文件等映射的大小。
    Slab:           内核数据结构缓存的大小，可以减少申请和释放内存带来的消耗。
    SReclaimable:   可收回Slab的大小。
    SUnreclaim：    不可收回Slab的大小（SUnreclaim+SReclaimable＝Slab）。
    PageTables：    管理内存分页页面的索引表的大小。
    NFS_Unstable:   不稳定页表的大小。
     */

    /**
     * 通过系统api获取当前可用内存大小
     */
    fun getAvailMemory(cx: Context?): Long {
        if (cx == null) {
            return 0L
        }
        val am = cx.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val mi = ActivityManager.MemoryInfo()
        am.getMemoryInfo(mi)
        Log.i(
            TAG,
            "Available memory: " + mi.availMem
        )
        return mi.availMem / BYTES_PER_MEGA // 将获取的内存大小规格化
    }

    /**
     * 通过系统api获取全部内存大小
     */
    fun getTotalMemory(cx: Context?): Long {
        if (cx == null) {
            return 0L
        }
        val am = cx.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val mi = ActivityManager.MemoryInfo()
        am.getMemoryInfo(mi)
        Log.i(
            TAG,
            "Total memory: " + mi.totalMem
        )
        return mi.totalMem / BYTES_PER_MEGA // 将获取的内存大小规格化
    }

    /**
     * 字符串处理，得到需要的数据信息
     *
    MemTotal:        7841952 kB  所有可用RAM大小。
    MemFree:          721656 kB  LowFree与HighFree的总和，被系统留着未使用的内存。
    MemAvailable:    3863868 kB  表示当前系统中可用的内存大小（以千字节为单位）。该值包括空闲内存和已使用但可回收的内存。
    Buffers:          227140 kB
    Cached:          1832872 kB
    SwapCached:            0 kB
    Active:          1143532 kB
     ····
     */
    fun getTotalMemory(): Array<Long> {
        val sb= loadTotalLine()
        mMemTotal = sb.split("\n")[0].replace(Regex("\\D+"), "").toLong()
        mMemAvail = sb.split("\n")[2].replace(Regex("\\D+"), "").toLong()
        return arrayOf(mMemTotal / 1024, mMemAvail / 1024)
    }

    /**
     * 通过读取meminfo文件获取系统全部内存
     */
    private fun loadTotalLine():String{
        val cmd = "/proc/meminfo"
        val sb = StringBuffer()
        var reader:BufferedReader?=null
        try {
            reader = BufferedReader(InputStreamReader(FileInputStream(cmd)), 1000)
            for(i in 0..3){
                sb.append(reader.readLine()).append("\n")
            }
        } catch (ex: Exception) {
            ex.printStackTrace()
        }finally {
            reader?.close()
        }
        return sb.toString()
    }
}